﻿using AVIS.OutBound.WizardAgent.Helpers;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Xml.Linq;

namespace AVIS.OutBound.WizardAgent
{
    /// <summary>
    /// 获取指定订单号的预订信息的Wizard服务
    /// </summary>
    public class WizardVehRetResAgent
    {
        protected static readonly log4net.ILog _LogWizardOrder = log4net.LogManager.GetLogger("WizardOrderXml");

        /// <summary>
        /// 提交订单信息到Wizard
        /// </summary>
        /// <param name="request"></param>
        /// <returns></returns>
        public SubmitOrderResponse SubmitOrder(SubmitOrderRequest request)
        {
            // 检查请求参数是否正确
            request.CheckRequest();

            // 请求Wizard接口新增订单（OTA_VehAvailRate）
            var response = WizardCacheHelper.GetResponseXml<SubmitOrderResponse>(request, (xml) =>
            {
                _LogWizardOrder.InfoFormat("提交订单请求XML：{1}{0}", xml, Environment.NewLine);
                var responseXML = WizardHttpClient.PostXml(xml);
                _LogWizardOrder.InfoFormat("订单返回响应XML：{1}{0}", responseXML, Environment.NewLine);
                return responseXML;
            });

            // 解析车组套餐的XML
            if (!response.HasError)
            {
                var responseXDoc = XDocument.Parse(response.ResponseString);
                response.Data = FillOrderWithXml(responseXDoc);

                // 记录日志
                // LogWriter.Info(string.Format("订单提交成功，订单号：{0}，客户的姓：{1}", response.Data.OrderNo, request.Surname));
                // LogWriter.Error(string.Format("订单提交成功，订单号：{0}，客户的姓：{1}", response.Data.OrderNo, request.Surname));
            }
            return response;
        }

        /// <summary>
        /// 取消订单（Wizard）
        /// </summary>
        /// <param name="request"></param>
        /// <returns></returns>
        public CancelOrderResponse CancelOrder(CancelOrderRequest request)
        {
            // 检查请求参数是否正确
            request.CheckRequest();

            // 请求Wizard接口获取指定套餐包含有效车型组（OTA_VehAvailRate）
            var response = WizardCacheHelper.GetResponseXml<CancelOrderResponse>(request, (xml) =>
            {
                return WizardHttpClient.PostXml(xml);
            });

            // 解析车组套餐的XML
            if (!response.HasError)
            {
                var responseXDoc = XDocument.Parse(response.ResponseString);
                response.Data = FillCancelOrderWithXml(responseXDoc);

                // 记录日志
                //LogWriter.Info(string.Format("订单取消成功，订单号：{0}，客户的姓：{1}", request.ReservationNumber, request.Surname));
                // LogWriter.Error(string.Format("订单取消成功，订单号：{0}，客户的姓：{1}", request.ReservationNumber, request.Surname));
            }

            return response;
        }

        /// <summary>
        /// 获取指定订单号的预订信息
        /// </summary>
        /// <remarks>
        /// 对应于Wizard的接口：
        ///     请求：OTA_VehRetResRQ——Vehicle Retrieve Reservation Request
        ///     响应：OTA_VehRetResRS——Vehicle Retrieve Reservation Response
        /// </remarks>
        public OrderQueryResponse OrderQuery(OrderQueryRequest request)
        {
            // 检查请求参数是否正确
            request.CheckRequest();

            // 请求Wizard接口获取指定订单号的预订信息（OTA_VehRetResRQ）
            var response = WizardCacheHelper.GetResponseXml<OrderQueryResponse>(request, (xml) =>
            {
                return WizardHttpClient.PostXml(xml);
            });

            // 解析车组套餐的XML
            if (!response.HasError)
            {
                var responseXDoc = XDocument.Parse(response.ResponseString);
                response.Data = FillOrderQueryFromXml(responseXDoc.Root);
            }

            return response;
        }

        #region 解析预订信息的XML

        private OrderQueryDto FillOrderQueryFromXml(XElement parentXElement)
        {
            var xVehReservation = XmlHelpler.FindXElement(parentXElement, "VehReservation", WizardConsts.XNamespace);
            var xPersonName = XmlHelpler.FindXElement(xVehReservation, "PersonName", WizardConsts.XNamespace);
            var xPaymentCard = XmlHelpler.FindXElement(xVehReservation, "PaymentCard", WizardConsts.XNamespace);
            var xVehSegmentCore = XmlHelpler.FindXElement(xVehReservation, "VehSegmentCore", WizardConsts.XNamespace);
            var xVehicle = XmlHelpler.FindXElement(xVehSegmentCore, "Vehicle", WizardConsts.XNamespace);
            var xRentalRate = XmlHelpler.FindXElement(xVehSegmentCore, "RentalRate", WizardConsts.XNamespace);
            var xPricedCoverages = XmlHelpler.FindXElement(xVehReservation, "PricedCoverages", WizardConsts.XNamespace);
            var xPricedEquips = XmlHelpler.FindXElement(xVehSegmentCore, "PricedEquips", WizardConsts.XNamespace);
            var xTPA_Extensions = XmlHelpler.FindXElement(xVehSegmentCore, "TPA_Extensions", WizardConsts.XNamespace);

            var orderQueryDto = new OrderQueryDto();
            orderQueryDto.ParsePersonNameXml(xPersonName);                      // 解析客户姓名
            orderQueryDto.ParsePaymentCardXml(xPaymentCard);                    // 解析客户支付的银行卡信息
            orderQueryDto.ParseVehSegmentCoreXml(xVehSegmentCore);              // 解析订单的主要信息，订单号，价格
            orderQueryDto.CarGroup.ParseVehicleXml(xVehicle);                   // 解析车组的基本信息（SIPPCode，ModelName，PictureURL）
            orderQueryDto.CarGroup.ParseRentalRateXml(xRentalRate);             // 解析车组的套餐价格代码、限制里程数、收费价格说明
            orderQueryDto.CarGroup.ParsePricedCoveragesXml(xPricedCoverages);   // 解析套餐价格包含的保险项目
            orderQueryDto.CarGroup.ParsePricedEquipsXml(xPricedEquips);         // 解析车辆装备等增值服务
            orderQueryDto.CarGroup.ParseReferenceXml(null, xVehicle);   // 解析车辆功能特征（比如：自动挡、4座等）
            orderQueryDto.ParseCouponDiscountAmount(xTPA_Extensions);           // 解析优惠信息的计算

            return orderQueryDto;
        }

        #endregion

        #region 解析订单结果的XML
        public OrderDto FillOrderWithXml(XDocument doc)
        {
            OrderDto orderDto = null;

            // 查找有效的车辆装备
            var xVehSegmentCore = XmlHelpler.FindXElement(doc.Root, "VehSegmentCore", WizardConsts.XNamespace);
            if (xVehSegmentCore != null)
            {
                orderDto = new OrderDto();
                orderDto.OrderNo = XmlHelpler.ParseValue(XmlHelpler.FindXElement(xVehSegmentCore, "ConfID", WizardConsts.XNamespace), "ID");
                orderDto.QuotedTMI = double.Parse(XmlHelpler.ParseValue(XmlHelpler.FindXElement(xVehSegmentCore, "TotalCharge", WizardConsts.XNamespace), "EstimatedTotalAmount"));
                orderDto.CurrencyCode = XmlHelpler.ParseValue(XmlHelpler.FindXElement(xVehSegmentCore, "TotalCharge", WizardConsts.XNamespace), "CurrencyCode");
                orderDto.CNAmount = 0;
            }

            return orderDto;
        }
        #endregion

        public bool FillCancelOrderWithXml(XDocument doc)
        {
            // 查找有效的车辆装备
            var xVehCancelRSCore = XmlHelpler.FindXElement(doc.Root, "VehCancelRSCore", WizardConsts.XNamespace);
            return XmlHelpler.ParseValue(xVehCancelRSCore, "CancelStatus") == "Cancelled";
        }
    }

    public static class OrderQueryDtoExtension
    {
        public static void ParsePersonNameXml(this OrderQueryDto dto, XElement PersonNameElement)
        {
            if (PersonNameElement == null)
                return;

            var xSurname = XmlHelpler.FindXElement(PersonNameElement, "Surname", WizardConsts.XNamespace);
            var xGivenName = XmlHelpler.FindXElement(PersonNameElement, "GivenName", WizardConsts.XNamespace);

            dto.Surname = XmlHelpler.ParseValue(xSurname);
            dto.Firstname = XmlHelpler.ParseValue(xGivenName);
        }

        public static void ParsePaymentCardXml(this OrderQueryDto dto, XElement PaymentCardElement)
        {
            if (PaymentCardElement == null)
                return;

            dto.MaskedCardNumber = XmlHelpler.ParseValue(PaymentCardElement, "MaskedCardNumber");
            dto.CardType = XmlHelpler.ParseValue(PaymentCardElement, "CardType");
        }

        public static void ParseVehSegmentCoreXml(this OrderQueryDto dto, XElement VehSegmentCoreElement)
        {
            if (VehSegmentCoreElement == null)
                return;

            var xConfID = XmlHelpler.FindXElement(VehSegmentCoreElement, "ConfID", WizardConsts.XNamespace);
            var xVehMakeModel = XmlHelpler.FindXElement(VehSegmentCoreElement, "VehMakeModel", WizardConsts.XNamespace);
            var xRateQualifier = XmlHelpler.FindXElement(VehSegmentCoreElement, "RateQualifier", WizardConsts.XNamespace);
            var xTotalCharge = XmlHelpler.FindXElement(VehSegmentCoreElement, "TotalCharge", WizardConsts.XNamespace);
            var xVehRentalCore = XmlHelpler.FindXElement(VehSegmentCoreElement, "VehRentalCore", WizardConsts.XNamespace);
            var xPickUpLocation = XmlHelpler.FindXElement(xVehRentalCore, "PickUpLocation", WizardConsts.XNamespace);
            var xReturnLocation = XmlHelpler.FindXElement(xVehRentalCore, "ReturnLocation", WizardConsts.XNamespace);

            dto.OrderNo = XmlHelpler.ParseValue(xConfID, "ID");
            dto.PickupDateTime = DateTime.Parse(XmlHelpler.ParseValue(xVehRentalCore, "PickUpDateTime"));
            dto.ReturnDateTime = DateTime.Parse(XmlHelpler.ParseValue(xVehRentalCore, "ReturnDateTime"));
            dto.PickUpStoreCode = XmlHelpler.ParseValue(xPickUpLocation, "LocationCode");
            dto.ReturnStoreCode = XmlHelpler.ParseValue(xReturnLocation, "LocationCode");
            dto.SIPPCode = XmlHelpler.ParseValue(xVehMakeModel, "Code");
            dto.RateCode = XmlHelpler.ParseValue(xRateQualifier, "RateQualifier");
            dto.AWD = XmlHelpler.ParseValue(xRateQualifier, "CorpDiscountNmbr");
            dto.CurrencyCode = XmlHelpler.ParseValue(xTotalCharge, "CurrencyCode");

            // 订单价格
            var strQuotedTMI = XmlHelpler.ParseValue(xTotalCharge, "EstimatedTotalAmount");
            double QuotedTMI = 0;
            if (double.TryParse(strQuotedTMI, out QuotedTMI))
            {
                dto.QuotedTMI = QuotedTMI;
            }
            //else
            //{
            //    LogWriter.Info(string.Format("解析订单的价格报错，对应的XML为：{0}", xTotalCharge));
            //}
        }

        public static void ParseCouponDiscountAmount(this OrderQueryDto dto, XElement TPA_ExtensionsElement)
        {
            /*  解析以下内容的数据
             *<TPA_Extensions>
                <Charge Description="Coupon Discount Amount" Amount="27.27" CurrencyCode="AUD" />
                <Reference Type="CouponDescription" ID="DIDI GLOBAL ROAD TRIPS GUIDE-PAPERLESS-F" />
                <Reference Type="CouponType" ID="T" />
              </TPA_Extensions>
             */

            if (TPA_ExtensionsElement == null)
                return;

            var xCharge = XmlHelpler.FindXElement(TPA_ExtensionsElement, "Charge", WizardConsts.XNamespace);
            if (xCharge != null)
            {
                var description = XmlHelpler.ParseValue(xCharge, "Description");
                if (description.Equals("Coupon Discount Amount", StringComparison.CurrentCultureIgnoreCase))
                {
                    double amount = 0;
                    if (double.TryParse(XmlHelpler.ParseValue(xCharge, "Amount"), out amount))
                    {
                        dto.CouponDiscountAmount = amount;
                    }

                    dto.CouponDiscountCurrencyCode = XmlHelpler.ParseValue(xCharge, "CurrencyCode");
                }
            }
        }
    }
}
